home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech's Sprocket™ / Sprocket (original from 1994) / SprocketSample / DocWindow.cp < prev    next >
Encoding:
Text File  |  1994-10-20  |  9.2 KB  |  388 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        DocWindow.cp
  3.  
  4.     Contains:    A simple document window
  5.                 
  6.     Written by: Dave Falkenburg
  7.     
  8.     Copyright:    © 1993-94 by Dave Falkenburg, all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.     
  12.          <4>     9/27/94    DRF        Changes for Dave Mark: AppLib.h is now Sprocket.h.
  13.          <3>      9/9/94    DRF        Reordered headers and removed redundant #includes.
  14.          <2>      9/4/94    DRF        Added scroll bars and revised dragging methods.
  15.  
  16.     To Do:        Figure out if any of these methods should move to TWindow
  17.  */
  18.  
  19. #include "Sprocket.h"
  20. #include "DocWindow.h"
  21.  
  22. #include <LowMem.h>        //    for LMGetCurApName()
  23. #include <ToolUtils.h>    //    for NumToString()
  24. #include <Icons.h>        //    for PlotIconID
  25.  
  26.  
  27. unsigned long        TDocWindow::fgUntitledTagCount = 0;
  28.  
  29. const short            kHeaderHeight = 20;
  30.  
  31. const short            kFirstSpinningArrowIconID = 801;
  32. const short            kLastSpinningArrowIconID = 808;
  33.  
  34. const short            kDocWindowTemplateID = 1026;
  35.  
  36.  
  37.  
  38. static pascal void    DocWindowControlActionProc(ControlHandle theControl,short partCode);
  39. static void            SpinDocWindowArrows(TDocWindow * windowToSpin);
  40.  
  41.  
  42. //    Functions which are called from external scope, but in turn invoke
  43. //    DocWindow methods. These really could be moved to "Window.h"
  44.  
  45. static ControlActionUPP
  46. DocWindowControlAction = NewControlActionProc(DocWindowControlActionProc);
  47.  
  48. static pascal void
  49. DocWindowControlActionProc(ControlHandle theControl,short partCode)
  50.     {
  51.     TDocWindow * aDocWindow = NULL;
  52.     
  53.     aDocWindow = (TDocWindow *) GetControlReference(theControl);
  54.  
  55.     if (aDocWindow)
  56.         aDocWindow->DoControlAction(theControl,partCode);
  57.     }
  58.  
  59.  
  60. static void
  61. SpinDocWindowArrows(TDocWindow * windowToSpin)
  62.     {
  63.     while (1)
  64.         {
  65.         windowToSpin->SpinHeaderArrows();
  66.         YieldToAnyThread();
  67.         }
  68.     }
  69.  
  70.  
  71.  
  72. //    methods
  73.  
  74. TDocWindow::TDocWindow()
  75.     {
  76.     OSErr    err;
  77.  
  78.     fCurrentSpinningArrowIconID = kFirstSpinningArrowIconID;
  79.     fVerticalScrollActive = fHorizontalScrollActive = false;
  80.  
  81.     fCanAcceptDrag = false;
  82.     fDragTargetRgn = NULL;
  83.  
  84.     TDocWindow::fgUntitledTagCount++;            //    Starts out as zero but we want “Untitled-1”
  85.     this->CreateWindow();
  86.     
  87.     if (gHasThreadManager)
  88.         {
  89.         err = NewThread(kCooperativeThread,(ThreadEntryProcPtr) SpinDocWindowArrows,this,0,0,nil,&fSpinnerThreadID);
  90.         if (err != noErr)
  91.             DebugStr((StringPtr) "\pNewThread failed");
  92.         }
  93.     }
  94.  
  95. TDocWindow::~TDocWindow()
  96.     {
  97.     OSErr    err;
  98.  
  99.     //    NEWS OF THE WEIRD!
  100.     //    If you pass true for recyleThread param, the heap block for the stack isn’t
  101.     //    disposed— it gets placed in the default cooperative thread pool of “premade”
  102.     //    threads.
  103.     //
  104.     //    To optimize memory usage, I might just want to go ahead and create
  105.     //    a thread pool at application startup so we can avoid moving memory around
  106.     //    so much.
  107.     
  108.     if (gHasThreadManager)
  109.         {
  110.         err = DisposeThread(fSpinnerThreadID,nil,false);
  111.         if (err != noErr)
  112.             DebugStr((StringPtr) "\pDisposeThread failed");
  113.         }
  114.     }
  115.  
  116.     
  117. WindowPtr
  118. TDocWindow::MakeNewWindow(WindowPtr behindWindow)
  119.     {
  120.     WindowPtr    aWindow = GetNewColorOrBlackAndWhiteWindow(kDocWindowTemplateID,nil,behindWindow);
  121.     Str255        titleString;
  122.     GrafPtr        savedPort;
  123.     Rect        scrollRect;
  124.     
  125.     GetPort(&savedPort);
  126.     if (aWindow)
  127.         {
  128.         //    make the window exciting & different
  129.         
  130.         //    Can’t call nudge because it assumes the window is visible!
  131.         
  132.         //    Nudge(fgUntitledTagCount * kHeaderHeight,fgUntitledTagCount * kHeaderHeight);
  133.     
  134.         GetWTitle(aWindow,titleString);
  135.         if (StrLength(titleString) != 0)
  136.             {
  137.             Str255 numberString;
  138.             
  139.             NumToString(fgUntitledTagCount,numberString);
  140.             BlockMove(&numberString[1],&titleString[titleString[0]+1],numberString[0]);
  141.             titleString[0] += numberString[0];
  142.             }
  143.         SetWTitle(aWindow,titleString);
  144.  
  145.         SetPort(aWindow);
  146.  
  147.         //    create vertical scroll bar
  148.         scrollRect.top = aWindow->portRect.top + kHeaderHeight -1;
  149.         scrollRect.left = aWindow->portRect.right - kScrollbarWidth + 1;
  150.         scrollRect.bottom = aWindow->portRect.bottom - kScrollbarWidth + kScrollbarTweak;
  151.         scrollRect.right = aWindow->portRect.right + 1;
  152.  
  153.         fVerticalScroll = NewControl(aWindow,&scrollRect,"\p", true,/* value = */ 0 ,/* min = */ 0, /* max = */ 255, scrollBarProc, (long) this);
  154.         SetControlAction(fVerticalScroll,DocWindowControlAction);
  155.  
  156.         //    create horizontal scroll bar
  157.         scrollRect.top = aWindow->portRect.bottom - kScrollbarWidth + 1;
  158.         scrollRect.left = aWindow->portRect.left -1;
  159.         scrollRect.bottom = aWindow->portRect.bottom + 1;
  160.         scrollRect.right = aWindow->portRect.right - kScrollbarWidth + kScrollbarTweak;
  161.         fHorizontalScroll = NewControl(aWindow,&scrollRect,"\p", true,/* value = */ 0 ,/* min = */ 0, /* max = */ 255, scrollBarProc, (long) this);
  162.         SetControlAction(fHorizontalScroll,DocWindowControlAction);
  163.  
  164.         ShowWindow(aWindow);
  165.         }
  166.     SetPort(savedPort);
  167.  
  168.     return aWindow;
  169.     }
  170.  
  171.  
  172. void
  173. TDocWindow::Activate(Boolean activating)
  174.     {
  175.     short    verticalHiliteValue,horizontalHiliteValue;
  176.     
  177.     if (activating)
  178.         {
  179.         verticalHiliteValue = (fVerticalScrollActive ? 0 : 255);
  180.         horizontalHiliteValue = (fHorizontalScrollActive ? 0 : 255);
  181.         }
  182.     else
  183.         {
  184.         verticalHiliteValue = horizontalHiliteValue = 254;
  185.          }
  186.  
  187.     HiliteControl(fVerticalScroll,verticalHiliteValue);
  188.     HiliteControl(fHorizontalScroll,horizontalHiliteValue);
  189.  
  190.     DrawJustTheGrowIcon(fWindow);
  191.     }
  192.  
  193.  
  194. void
  195. TDocWindow::AdjustCursor(EventRecord * /* anEvent */)
  196.     {
  197.     }
  198.  
  199.  
  200. void
  201. TDocWindow::Draw(void)
  202.     {
  203.     EraseRect(&fWindow->portRect);
  204.  
  205.     MoveTo(0,kHeaderHeight-3); LineTo(fWindow->portRect.right,kHeaderHeight-3);
  206.     MoveTo(0,kHeaderHeight-1); LineTo(fWindow->portRect.right,kHeaderHeight-1);
  207.  
  208.     UpdateControls(fWindow,fWindow->visRgn);
  209.  
  210.     DrawJustTheGrowIcon(fWindow);
  211.     }
  212.  
  213.     
  214. void
  215. TDocWindow::Click(EventRecord * anEvent)
  216.     {
  217.     ControlHandle    theControl = NULL;
  218.     short            theControlPartCode;
  219.     
  220.     theControlPartCode = FindControl(anEvent->where,fWindow,&theControl);
  221.     
  222.     if (theControl != NULL)
  223.         {
  224.         //    NOTE: NON-NULL action procs don’t work for scrollbar thumbs!
  225.         if (theControlPartCode != inThumb)
  226.             (void) TrackControl(theControl,anEvent->where,DocWindowControlAction);
  227.         else
  228.             {
  229.             //    You might ask: What the heck is CW doing to make this work???
  230.             //    They don’t call TrackControl, instead they roll their own
  231.             //    using TestControl & SetControlValue. This is left as an
  232.             //    excercise to the reader, and we do the OLD HI method of
  233.             //    dragging a ghost thumb around
  234.  
  235.             (void) TrackControl(theControl,anEvent->where,NULL);
  236.             }
  237.         }
  238.     else
  239.         {
  240.         if (FrontNonFloatingWindow() != fWindow)
  241.             {
  242.             this->Select();
  243.             }
  244.         else
  245.             {
  246.             }
  247.         }
  248.     }
  249.  
  250.  
  251. void
  252. TDocWindow::AdjustForNewWindowSize(Rect *oldSize,Rect * newSize)
  253.     {
  254.     Rect    growBoxRect;
  255.     
  256.     //    Invalidate the old grow box
  257.     growBoxRect.top = oldSize->bottom - kScrollbarWidth;
  258.     growBoxRect.bottom = oldSize->bottom;
  259.     growBoxRect.left = oldSize->right - kScrollbarWidth;
  260.     growBoxRect.right = oldSize->right;
  261.     InvalRect(&growBoxRect);
  262.     
  263.     //    HideControl does an InvalRect for us, and hides all the jerky control movement from the user.
  264.     HideControl(fVerticalScroll);
  265.     HideControl(fHorizontalScroll);
  266.  
  267.     MoveControl(fVerticalScroll,newSize->right - kScrollbarWidth + 1,newSize->top + kHeaderHeight-1);
  268.     MoveControl(fHorizontalScroll,newSize->left - 1,newSize->bottom - kScrollbarWidth + 1);
  269.  
  270.     SizeControl(fVerticalScroll,kScrollbarWidth,(newSize->bottom - newSize->top) - kHeaderHeight + 1 - kScrollbarWidth + kScrollbarTweak);
  271.     SizeControl(fHorizontalScroll,(newSize->right - newSize->left + 1) - kScrollbarWidth + kScrollbarTweak,kScrollbarWidth);
  272.  
  273.     //    Now that we’ve moved & resized the scroll bars, show them.
  274.     ShowControl(fVerticalScroll);
  275.     ShowControl(fHorizontalScroll);
  276.  
  277.     DrawJustTheGrowIcon(fWindow);
  278.     }
  279.  
  280.  
  281. Boolean
  282. TDocWindow::Close(void)
  283.     {
  284.     StandardCloseResult    result;
  285.     Str255                title;
  286.     
  287.     GetWTitle(this->fWindow,title);
  288.     result = StandardCloseDocument(LMGetCurApName(),title,false,false);
  289.  
  290.     if (result != kCancelSaveDocument)
  291.         {
  292.         return TWindow::Close();
  293.         }
  294.     return false;
  295.     }
  296.  
  297.  
  298. OSErr
  299. TDocWindow::DragEnterWindow(DragReference theDrag)
  300.     {
  301.     //    preflight to determine if we can accept any of the drag
  302.     
  303.     fCanAcceptDrag = true;        //    accept anything for now
  304.  
  305.     fDragTargetRgn = NewRgn();
  306.     SetRectRgn( fDragTargetRgn,
  307.                 fWindow->portRect.left,
  308.                 fWindow->portRect.top + kHeaderHeight,
  309.                 fWindow->portRect.right-kScrollbarWidth+1,
  310.                 fWindow->portRect.bottom-kScrollbarWidth+1);
  311.     
  312.     return this->DragInWindow(theDrag);
  313.     }
  314.  
  315.  
  316. OSErr
  317. TDocWindow::DragInWindow(DragReference theDrag)
  318.     {
  319.     if (fCanAcceptDrag)
  320.         {
  321.         Point    mouseLoc, pinnedMouseLoc;
  322.  
  323.         (void) GetDragMouse(theDrag,&mouseLoc,&pinnedMouseLoc);
  324.         GlobalToLocal(&mouseLoc);
  325.         
  326.         if (PtInRgn(mouseLoc,fDragTargetRgn))
  327.             ShowDragHilite(theDrag,fDragTargetRgn,true);
  328.         else
  329.             HideDragHilite(theDrag);
  330.         }
  331.         
  332.     return noErr;
  333.     }
  334.  
  335.  
  336. OSErr
  337. TDocWindow::DragLeaveWindow(DragReference theDrag)
  338.     {
  339.     fCanAcceptDrag = false;
  340.     DisposeRgn(fDragTargetRgn);    
  341.     HideDragHilite(theDrag);
  342.     return noErr;
  343.     }
  344.  
  345.  
  346. OSErr
  347. TDocWindow::HandleDrop(DragReference /* theDrag */)
  348.     {
  349.     return noErr;
  350.     }
  351.  
  352.  
  353. void
  354. TDocWindow::DoControlAction(ControlHandle whichControl,short /* whichPart */)
  355.     {
  356.     if (whichControl == fVerticalScroll)
  357.         {
  358.         }
  359.     else if (whichControl == fHorizontalScroll)
  360.         {
  361.         }
  362.     }
  363.  
  364.  
  365. void
  366. TDocWindow::SpinHeaderArrows()
  367.     {
  368.     GrafPtr    oldPort;
  369.     
  370.     GetPort(&oldPort);
  371.     SetPort(fWindow);
  372.     
  373.     Rect    r;
  374.     
  375.     fCurrentSpinningArrowIconID++;
  376.     
  377.     if (fCurrentSpinningArrowIconID > kLastSpinningArrowIconID)
  378.         fCurrentSpinningArrowIconID = kFirstSpinningArrowIconID;
  379.     
  380.     r.top = fWindow->portRect.top;
  381.     r.left = fWindow->portRect.left+4;
  382.     r.bottom = r.top + 16;
  383.     r.right = r.left + 16;
  384.     (void) PlotIconID(&r,atNone,ttNone,fCurrentSpinningArrowIconID);
  385.  
  386.     SetPort(oldPort);
  387.     }
  388.